package org.redis.cluster;

import org.redis.cluster.config.ConfigManager;
import org.redis.cluster.config.ConfigManagerFactory;
import org.redis.cluster.config.RegistryConfig;
import org.redis.cluster.config.ServerConfig;
import org.redis.cluster.event.EventPusher;
import org.redis.cluster.event.EventPusherFactory;
import org.redis.cluster.extension.DefaultExtensionLoader;
import org.redis.cluster.extension.ExtensionLoader;
import org.redis.cluster.registry.Registry;
import org.redis.cluster.registry.RegistryFactory;
import org.redis.cluster.transport.server.Server;
import org.redis.cluster.transport.server.ServerChannel;
import org.redis.cluster.transport.server.ServerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DefaultRedisCluster implements RedisCluster {
	
	private final static String SERVER_FACTORY="serverFactory";
	
	private final static String REGISTRY_FACTORY="registryFactory";
	
	private final static String CONFIG_MANAGER_FACTORY="configManagerFactory";
	
	private final static String EVENT_PUSHER_FACTORY="eventPusherFactory";
	
	protected final Logger logger=LoggerFactory.getLogger(getClass());
	
	private ConfigManager configManager;
	private Registry registry;
	private ExtensionLoader extensionLoader;
	private EventPusher eventPusher;
	
	private Server server;
	private ServerChannel serverChannel;
	
	public DefaultRedisCluster() {
		if(logger.isInfoEnabled()) {
			logger.info("准备初始化扩展");
		}
		
		this.extensionLoader=initExtensionLoader();
		
		if(logger.isInfoEnabled()) {
			logger.info("初始化扩展完成");
		}
		
		if(logger.isInfoEnabled()) {
			logger.info("准备读取配置");
		}
		
		this.configManager=initConfigManager();
		
		if(logger.isInfoEnabled()) {
			logger.info("读取到配置 - {}",this.configManager);
		}
		
		if(logger.isInfoEnabled()) {
			logger.info("准备初始化注册中心 - {}",this.configManager.getReigstryConfig());
		}
		
		if(logger.isInfoEnabled()) {
			logger.info("准备初始化事件推送");
		}
		
		this.eventPusher=initEventPusher();
		
		if(logger.isInfoEnabled()) {
			logger.info("初始化事件推送完成");
		}
		
		this.registry=initRegistry(this.configManager.getReigstryConfig());
		
		if(logger.isInfoEnabled()) {
			logger.info("初始化注册中心完成 ");
		}
	}
	
	@Override
	public void startup() {
		if(logger.isInfoEnabled()) {
			logger.info("{}准备启动",Constants.NAME);
		}
		
		startBefore();
		
		if(logger.isInfoEnabled()) {
			logger.info("准备启动服务 - {}",this.configManager.getServerConfig());
		}
		
		Server server=initServer(configManager.getServerConfig());
		this.server=server;
		this.serverChannel=doServerStartup(server);
		
		if(logger.isInfoEnabled()) {
			logger.info("启动服务完成");
		}
		
		if(logger.isInfoEnabled()) {
			logger.info("准备注册服务");
		}
		
		registerServer();
		
		if(logger.isInfoEnabled()) {
			logger.info("注册服务完成");
		}
		if(logger.isInfoEnabled()) {
			logger.info("{}启动完成",Constants.NAME);
		}
		
		startAfter();
	}

	private void startAfter() {
		
	}
	
	private void startBefore() {
		
	}
	
	@Override
	public void shutdown() {
		shutdownBefore();
		unregister();
		doServerShutdown();
		doExtensionLoaderDestroy();
		shutdownAfter();
	}
	
	private void shutdownAfter() {
		
	}
	
	private void shutdownBefore() {
		
	}
	
	protected void doServerShutdown() {
		serverChannel.shutdown();
	}
	
	protected void doExtensionLoaderDestroy() {
		extensionLoader.destroy();
	}
	
	private ServerChannel doServerStartup(Server server) {
		return server.startup();
	}
	
	protected void registerServer() {
		registry.registerServer(configManager.getServerConfig());
	}
	
	protected void unregister() {
		registry.unregisterServer(configManager.getServerConfig());
	}
	
	protected Server initServer(ServerConfig serverConfig) {
		return extensionLoader.load(SERVER_FACTORY, ServerFactory.class).getServer(serverConfig);
	}
	
	protected ConfigManager initConfigManager() {
		return extensionLoader.load(CONFIG_MANAGER_FACTORY, ConfigManagerFactory.class).getConfigManager();
	}
	
	protected Registry initRegistry(RegistryConfig registryConfig) {
		return extensionLoader.load(REGISTRY_FACTORY, RegistryFactory.class).getRegistry(registryConfig);
	}
	
	protected EventPusher initEventPusher() {
		return extensionLoader.load(EVENT_PUSHER_FACTORY,EventPusherFactory.class).getEventPusher();
	}
	
	protected ExtensionLoader initExtensionLoader() {
		ExtensionLoader extensionLoader=new DefaultExtensionLoader(this);
		extensionLoader.init();
		
		return extensionLoader;
	}
	
	@Override
	public ConfigManager getConfigManager() {
		return configManager;
	}

	@Override
	public Registry getRegistry() {
		return registry;
	}
	
	@Override
	public ExtensionLoader getExtensionLoader() {
		return extensionLoader;
	}
	
	@Override
	public EventPusher getEventPusher() {
		return eventPusher;
	}

}